package org.example.interceptor;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import org.example.common.SerializationInterface;
import org.example.entity.CalculateProto;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * rpc调用的动态代理类
 */
public class RpcInterceptor implements InvocationHandler {

    private Object target;

    public RpcInterceptor(Object target) {
        this.target = target;
    }

    public static Object createProxy(Object target) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(new RpcInterceptor(target));
        return enhancer.create();
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataInputStream in = (DataInputStream) objects[1];
        DataOutputStream out = (DataOutputStream) objects[2];
        //反序列化
        System.out.println("------服务端动态代理开始");
        byte[] bytes = new byte[100];
        int read = in.read(bytes);
        bos.write(bytes, 0, read);
        CalculateProto.Calculate calculate2 = null;
        byte[] clientRequest = bos.toByteArray();
        System.out.println("服务端收到的字节数组：" + Arrays.toString(clientRequest));
        //计算
        Class cls = (Class) objects[3];
        Constructor declaredConstructor = cls.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        SerializationInterface pojo = (SerializationInterface) declaredConstructor.newInstance();
        //反序列化
        SerializationInterface calculatepojo = (SerializationInterface) pojo.reverseSerialization(clientRequest);
        objects[0] = calculatepojo;
        //调用方法
        SerializationInterface invoke = (SerializationInterface) method.invoke(target, objects);
        //序列化发送给客户端
        byte[] responseBytes = invoke.toSerialization(invoke);
        System.out.println("服务端计算完后发送给客户端数据序列化后字节数组：" + Arrays.toString(responseBytes));
        out.write(responseBytes);
        out.flush();
        System.out.println("------动态代理结束");
        return invoke;
    }
}
